package com.hmdp.interceptor;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.hmdp.dto.UserDTO;
import com.hmdp.utils.UserHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static com.hmdp.utils.RedisConstants.LOGIN_USER_KEY;
import static com.hmdp.utils.RedisConstants.LOGIN_USER_TTL;

@Slf4j
public class RefreshTokenInterceptor extends HandlerInterceptorAdapter {
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 这里stringRedisTemplate无法通过@Autowired注入 因为这个类不受spring容器管理 所以采取有参构造 然后在配置类中调用有参构造注入
     * @param stringRedisTemplate
     */
    public RefreshTokenInterceptor(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //1.从请求头中获取token，并根据token从redis中获取用户信息
        String token = request.getHeader("authorization");
        if (StringUtils.isBlank(token)){
            return true;
        }
        String tokenKey = LOGIN_USER_KEY + request.getHeader("authorization");
        Map<Object, Object> userMap = stringRedisTemplate.opsForHash().entries(tokenKey);

        //2-1不存在则拦截，并响应401
        if (userMap.isEmpty()) {
            return true;
        }
        //2-2若存在用户信息，则放行,并将用户信息保存到ThreadLocal中
        UserDTO userDTO = new UserDTO();
        //2-3将获取的map类型的用户信息转换为userDto类型
        BeanUtil.fillBeanWithMap(userMap,userDTO, false);
        UserHolder.saveUser(userDTO);
        //刷新用户登陆状态有效期
        stringRedisTemplate.expire(tokenKey,LOGIN_USER_TTL, TimeUnit.MINUTES);
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("执行线程结束，清空threadLocal数据!");
        UserHolder.removeUser();
    }
}
